package com.example.campus.service.impl;

import cn.hutool.core.util.StrUtil;
import com.example.campus.mapper.ImageMapper;
import com.example.campus.mapper.LikeMapper;
import com.example.campus.mapper.LostAndFoundInfoMapper;
import com.example.campus.mapper.UserMapper;
import com.example.campus.pojo.entity.Like;
import com.example.campus.pojo.entity.User;
import com.example.campus.pojo.vo.InfoLikeVO;
import com.example.campus.pojo.vo.UserLikeVO;
import com.example.campus.service.LikeService;
import com.example.campus.utils.constant.RedisConstant;
import com.example.campus.utils.context.BaseContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class LikeServiceImpl implements LikeService {
    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private LostAndFoundInfoMapper lostAndFoundInfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ImageMapper imageMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void addByUser(Long infoId) {
        Like like = Like.builder()
                .userId(BaseContext.getCurrentId())
                .infoId(infoId)
                .createTime(LocalDateTime.now())
                .build();
        likeMapper.insert(like);
        String key = RedisConstant.CACHE_LIKE_COUNT_KEY + infoId;
        stringRedisTemplate.delete(key);
    }

    @Override
    public void removeByUser(Long infoId) {
        likeMapper.deleteByInfoIdAndUserId(infoId, BaseContext.getCurrentId());
        String key = RedisConstant.CACHE_LIKE_COUNT_KEY + infoId;
        stringRedisTemplate.delete(key);
    }

    @Override
    public List<UserLikeVO> getLikeListByUser() {
        Long userId = BaseContext.getCurrentId();
        Like select = Like.builder().userId(userId).build();
        List<Like> likes = likeMapper.getLikeList(select);
        List<UserLikeVO> userLikeVOS = new ArrayList<>();

        for (Like like : likes) {
            UserLikeVO userLikeVO = new UserLikeVO();
            BeanUtils.copyProperties(like, userLikeVO);
            String title = lostAndFoundInfoMapper.getById(like.getInfoId()).getTitle();
            userLikeVO.setInfoTitle(title);
            List<String> urls = imageMapper.getUrlByInfoId(like.getInfoId());
            if (urls != null && !urls.isEmpty()) {
                userLikeVO.setFirstImage(urls.get(0));
            }
            userLikeVOS.add(userLikeVO);
        }

        return userLikeVOS;
    }

    @Override
    public List<InfoLikeVO> getLikeListByInfo(Long infoId) {
        Like select = Like.builder().infoId(infoId).build();
        List<Like> likes = likeMapper.getLikeList(select);
        List<InfoLikeVO> infoLikeVOS = new ArrayList<>();

        for (Like like : likes) {
            InfoLikeVO infoLikeVO = new InfoLikeVO();
            BeanUtils.copyProperties(like, infoLikeVO);
            User user = userMapper.getById(like.getUserId());
            infoLikeVO.setUsername(user.getUsername());
            infoLikeVO.setAvatarPath(user.getAvatarPath());
            infoLikeVOS.add(infoLikeVO);
        }

        return infoLikeVOS;
    }

    @Override
    public Integer getLikeCount(Long infoId) {
        String key = RedisConstant.CACHE_LIKE_COUNT_KEY + infoId;
        String likeCountStr = stringRedisTemplate.opsForValue().get(key);

        if (StrUtil.isNotBlank(likeCountStr)) {
            return Integer.valueOf(likeCountStr);
        }

        Integer likeCount = likeMapper.getLikeCount(infoId);
        stringRedisTemplate.opsForValue().set(key, likeCount.toString(), RedisConstant.CACHE_LIKE_COUNT_TTL, TimeUnit.MINUTES);
        return likeCount;
    }

    @Override
    public Long getLikeTotal() {
        return likeMapper.getLikeTotal();
    }
}
